import*as e from"../../../core/common/common.js";import*as t from"../../../core/host/host.js";import*as n from"../../../core/i18n/i18n.js";import*as o from"../../../core/platform/platform.js";import{assertNotNullOrUndefined as i}from"../../../core/platform/platform.js";import*as a from"../../../core/sdk/sdk.js";import*as r from"../../../models/bindings/bindings.js";import*as s from"../../../models/breakpoints/breakpoints.js";import*as c from"../../../models/text_utils/text_utils.js";import*as l from"../../../models/workspace/workspace.js";import*as d from"../../../ui/components/helpers/helpers.js";import*as p from"../../../ui/components/icon_button/icon_button.js";import*as h from"../../../ui/components/input/input.js";import*as u from"../../../ui/components/legacy_wrapper/legacy_wrapper.js";import*as g from"../../../ui/components/render_coordinator/render_coordinator.js";import*as m from"../../../ui/legacy/legacy.js";import*as b from"../../../ui/lit-html/lit-html.js";import*as k from"../../../models/persistence/persistence.js";import*as f from"../../../ui/components/buttons/buttons.js";const x=new CSSStyleSheet;x.replaceSync(':host{flex:auto;display:flex;flex-direction:column}.code-snippet{width:100%;font-family:var(--source-code-font-family);font-size:var(--source-code-font-size);color:var(--color-text-secondary);text-overflow:ellipsis;overflow:hidden;white-space:nowrap;flex-shrink:100;cursor:pointer}.code-snippet:hover{color:var(--color-text-primary);text-decoration:underline}input{height:12px;width:12px;flex-shrink:0;margin:3px 0}details{border-top:1px solid var(--color-details-hairline)}details:not(.active){background-color:var(--color-background-elevation-1);opacity:30%}details > summary{height:18px;list-style:none;display:flex;padding:0 8px 0 6px;align-items:center}details > summary:hover{background-color:var(--color-background-elevation-1)}details > summary::before{display:block;user-select:none;-webkit-mask-image:var(--image-file-triangle-right);background-color:var(--icon-default);content:"";height:14px;min-width:14px;max-width:14px;margin-left:-4px;overflow:hidden;transition:transform 200ms}details[open] > summary::before{transform:rotate(90deg)}.group-header{display:inline-flex;align-items:center;width:100%;padding-right:8px;overflow:hidden}.group-icon-or-disable{justify-content:center;display:flex;width:16px;margin-left:2px}.group-header-title{margin-left:4px;font-weight:500;font-size:var(--source-code-font-size);text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.group-header-differentiator{font-weight:normal;color:var(--color-text-disabled);margin-left:8px}.group-hover-actions{display:flex;align-items:center;justify-content:right;font-size:10px;font-weight:500}.breakpoint-item-location-or-actions{min-width:20px;flex:0 0 auto;display:flex;padding-left:8px;justify-content:right}button{cursor:pointer;width:13px;height:13px;border:none;background-color:transparent;display:none;align-items:center;justify-content:center}button + span{padding-left:6px}button + button{padding-left:11px}summary:hover button{display:flex}button:hover devtools-icon{--icon-color:var(--icon-default-hover)}.type-indicator{--override-color-conditional-breakpoint:#f29900;--override-color-logpoint:#f439a0;border-right:4px solid;border-radius:0 2px 2px 0;border-color:transparent;height:16px}.breakpoint-item{display:flex;align-items:center;line-height:13px;height:20px;padding-right:8px}.breakpoint-item:hover{background-color:var(--color-background-elevation-1)}.breakpoint-item.hit{--override-breakpoint-hit-background:rgb(255 255 194);background-color:var(--override-breakpoint-hit-background)}.breakpoint-item.hit:focus{background-color:var(--legacy-focus-bg-color)}:host-context(.-theme-with-dark-background) .breakpoint-item.hit{background-color:hsl(46deg 98% 22%);color:var(--color-text-primary)}.-theme-with-dark-background .type-indicator,\n:host-context(.-theme-with-dark-background) .type-indicator{--override-color-conditional-breakpoint:#e9a33a;--override-color-logpoint:#e54d9b}.breakpoint-item.logpoint > label > .type-indicator{border-color:var(--override-color-logpoint)}.breakpoint-item.conditional-breakpoint > label > .type-indicator{border-color:var(--override-color-conditional-breakpoint)}.checkbox-label{display:flex;align-items:center}.checkbox-label > input{margin-left:16px;margin-right:6px}summary:hover .file-icon{display:none}.group-checkbox{margin:0;display:none}summary:hover .group-checkbox{display:flex}.location{line-height:14px;text-overflow:ellipsis;overflow:hidden}.breakpoint-item:hover button{display:flex}.pause-on-uncaught-exceptions{margin-top:3px}.pause-on-caught-exceptions{margin-bottom:3px}input:disabled + span{color:var(--color-text-disabled)}.pause-on-caught-exceptions > .checkbox-label > input,\n.pause-on-uncaught-exceptions > .checkbox-label > input{margin-left:6px}.pause-on-caught-exceptions > .checkbox-label > span,\n.pause-on-uncaught-exceptions > .checkbox-label > span{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.pause-on-uncaught-exceptions,\n.pause-on-caught-exceptions{line-height:13px;height:18px;padding-right:8px}details > summary:focus,\n.breakpoint-item:focus,\n.pause-on-uncaught-exceptions:focus,\n.pause-on-caught-exceptions:focus{background-color:var(--legacy-focus-bg-color);outline-width:0}\n/*# sourceURL=breakpointsView.css */\n');const v=e=>null!==e.getAttribute("data-first-pause")||null!==e.getAttribute("data-last-pause"),y=e=>!(e=>"treeitem"===e.getAttribute("role"))(e),w=e=>null!==e.getAttribute("open"),S=e=>e.querySelector("[data-first-breakpoint]"),E=e=>{const t=I(e);return t&&t instanceof HTMLDetailsElement?t?.querySelector("summary"):null},C=e=>e.querySelector("summary"),I=e=>{const t=e.nextElementSibling;return t&&t instanceof HTMLDetailsElement?t:null};async function T(e,t,n){if(v(e))return function(e,t){console.assert(v(e));let n=null;switch(t){case"ArrowUp":{const t=e.previousElementSibling;t instanceof HTMLElement&&(n=t,console.assert(v(n)));break}case"ArrowDown":{const t=e.nextElementSibling;if(t instanceof HTMLElement)if("tree"===t.getAttribute("role")){const e=t.querySelector("[data-first-group]");e&&(n=C(e))}else n=t,console.assert(v(n));break}}return n}(e,t);const o=e.parentElement;if(!(o&&o instanceof HTMLDetailsElement))throw new Error("The selected nodes should be direct children of an HTMLDetails element.");let i=null;switch(t){case"ArrowLeft":if(!y(e))return C(o);w(o)&&await n(o,!1);break;case"ArrowRight":if(y(e)){if(w(o))return S(o);await n(o,!0)}break;case"ArrowDown":if(y(e))i=w(o)?S(o):E(o);else{const t=e.nextElementSibling;i=t&&t instanceof HTMLDivElement?t:E(o)}break;case"ArrowUp":if(y(e)){const e=(e=>{const t=e.previousElementSibling;return t&&t instanceof HTMLDetailsElement?t:null})(o);if(e)i=w(e)?(e=>e.querySelector("[data-last-breakpoint]"))(e):C(e);else{const e=o.parentElement?.previousElementSibling;e instanceof HTMLElement&&(i=e)}}else{const t=e.previousElementSibling;t instanceof HTMLElement&&(i=t)}}return i}function B(e,t,n){const o=[];let i=t.filter((t=>t!==e));for(let t=n;t<e.length;++t){const n=e[t];if(o.push(n),i=i.filter((e=>e.length>t&&e[t]===n)),0===i.length)break}return o}function L(t,n){const o=t.map((t=>{const n=e.ParsedURL.ParsedURL.fromString(t)?.folderPathComponents.slice(1);return i(n),n.split("/").reverse()})),a=function(e){const t=e[0];let n=-1;for(let o=0;o<t.length&&-1===n;++o){const i=t[o];for(let t=1;t<e.length;++t){const a=e[t];if(a.length<=o||a[o]!==i){n=o;break}}}return-1===n?t.length:n}(o);for(let e=0;e<o.length;++e){const i=B(o[e],o,a).reverse().join("/");0===a?n.set(t[e],i+"/"):n.set(t[e],i+"/…/")}console.assert(new Set(n.values()).size===t.length,"Differentiators should be unique.")}function $(e){const t=new Map,n=new Map;for(const{name:n,url:o}of e)t.has(n)||t.set(n,[]),t.get(n)?.push(o);for(const e of t.values())e.length>1&&L(e,n);return n}var O=Object.freeze({__proto__:null,findNextNodeForKeyboardNavigation:T,getDifferentiatingPathMap:$});const A={pauseOnUncaughtExceptions:"Pause on uncaught exceptions",pauseOnCaughtExceptions:"Pause on caught exceptions",checked:"checked",unchecked:"unchecked",indeterminate:"mixed",breakpointHit:"{PH1} breakpoint hit",removeAllBreakpointsInFile:"Remove all breakpoints in file",disableAllBreakpointsInFile:"Disable all breakpoints in file",enableAllBreakpointsInFile:"Enable all breakpoints in file",editCondition:"Edit condition",editLogpoint:"Edit logpoint",removeBreakpoint:"Remove breakpoint",removeAllBreakpoints:"Remove all breakpoints",removeOtherBreakpoints:"Remove other breakpoints",revealLocation:"Reveal location",conditionCode:"Condition: {PH1}",logpointCode:"Logpoint: {PH1}"},M=n.i18n.registerUIStrings("panels/sources/components/BreakpointsView.ts",A),N=n.i18n.getLocalizedString.bind(void 0,M),D=g.RenderCoordinator.RenderCoordinator.instance();let R,H;class U{#e;#t=new WeakMap;#n;#o;#i;#a;#r;#s;#c=!1;#l=!1;constructor(t,n){this.#a=e.Settings.Settings.instance().createSetting("collapsedFiles",[]),this.#r=new Set(this.#a.get()),this.#e=t,this.#e.addEventListener(s.BreakpointManager.Events.BreakpointAdded,this.#d,this),this.#e.addEventListener(s.BreakpointManager.Events.BreakpointRemoved,this.#p,this),this.#n=n.moduleSetting("breakpointsActive"),this.#n.addChangeListener(this.update,this),this.#o=n.moduleSetting("pauseOnUncaughtException"),this.#o.addChangeListener(this.update,this),this.#i=n.moduleSetting("pauseOnCaughtException"),this.#i.addChangeListener(this.update,this)}static instance({forceNew:t,breakpointManager:n,settings:o}={forceNew:null,breakpointManager:s.BreakpointManager.BreakpointManager.instance(),settings:e.Settings.Settings.instance()}){return H&&!t||(H=new U(n,o)),H}static removeInstance(){H=null}static targetSupportsIndependentPauseOnExceptionToggles(){return!a.TargetManager.TargetManager.instance().targets().some((e=>e.type()===a.Target.Type.Node))}flavorChanged(e){this.update()}breakpointEditFinished(e,n){this.#s&&this.#s===e&&(n&&t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointConditionEditedFromSidebar),this.#s=void 0)}breakpointStateChanged(e,t){this.#h(e).forEach((e=>{e.breakpoint.setEnabled(t)}))}async breakpointEdited(t,n){const o=this.#h(t);let i;for(const e of o)(!i||e.uiLocation.compareTo(i.uiLocation)<0)&&(i=e);i&&(n&&(this.#s=i.breakpoint),await e.Revealer.reveal(i))}breakpointsRemoved(e){e.flatMap((e=>this.#h(e))).forEach((e=>e?.breakpoint.remove(!1)))}expandedStateChanged(e,t){t?this.#r.delete(e):this.#r.add(e),this.#u()}async jumpToSource(t){const n=this.#h(t).map((e=>e.uiLocation));let o;for(const e of n)(!o||e.compareTo(o)<0)&&(o=e);o&&await e.Revealer.reveal(o)}setPauseOnUncaughtExceptions(e){this.#o.set(e)}setPauseOnCaughtExceptions(e){this.#i.set(e)}async update(){if(this.#c=!0,!this.#l){for(this.#l=!0;this.#c;){this.#c=!1;const e=await this.getUpdatedBreakpointViewData();F.instance().data=e}this.#l=!1}}async getUpdatedBreakpointViewData(){const e=this.#n.get(),t=U.targetSupportsIndependentPauseOnExceptionToggles(),n=this.#o.get(),o=this.#i.get(),i=this.#g();if(!i.length)return{breakpointsActive:e,pauseOnCaughtExceptions:o,pauseOnUncaughtExceptions:n,independentPauseToggles:t,groups:[]};const a=this.#m(i),r=this.#b(i),[s,l]=await Promise.all([this.#k(a),this.#f()]),d=new Map;for(let e=0;e<a.length;e++){const t=a[e],n=t[0],o=n.uiLocation.uiSourceCode.url(),i=n.uiLocation.uiSourceCode.canononicalScriptId(),p=n.uiLocation,h=null!==l&&t.some((e=>e.uiLocation.id()===l.id())),u=r.get(p.lineId()).size>1,g=p.lineAndColumnText(u),m=s[e],b=m instanceof c.Text.Text?m.lineAt(p.lineNumber):m.lines[m.bytecodeOffsetToLineNumber(p.columnNumber??0)]??"";h&&this.#r.has(o)&&(this.#r.delete(o),this.#u());const k=!this.#r.has(o),f=this.#x(t),{type:x,hoverText:v}=this.#v(t),y={id:n.breakpoint.breakpointStorageId(),location:g,codeSnippet:b,isHit:h,status:f,type:x,hoverText:v};this.#t.set(y,t);let w=d.get(i);if(w)w.breakpointItems.push(y),w.expanded||=k;else{const e=this.#e.supportsConditionalBreakpoints(p.uiSourceCode);w={url:o,name:p.uiSourceCode.displayName(),editable:e,expanded:k,breakpointItems:[y]},d.set(i,w)}}return{breakpointsActive:e,pauseOnCaughtExceptions:o,pauseOnUncaughtExceptions:n,independentPauseToggles:t,groups:Array.from(d.values())}}#d(e){const t=e.data.breakpoint;return"USER_ACTION"===t.origin&&this.#r.has(t.url())&&(this.#r.delete(t.url()),this.#u()),this.update()}#p(e){const t=e.data.breakpoint;if(this.#r.has(t.url())){s.BreakpointManager.BreakpointManager.instance().allBreakpointLocations().some((e=>e.breakpoint.url()===t.url()))||(this.#r.delete(t.url()),this.#u())}return this.update()}#u(){this.#a.set(Array.from(this.#r.values()))}#v(e){const t=e.find((e=>Boolean(e.breakpoint.condition())))?.breakpoint;if(!t||!t.condition())return{type:"REGULAR_BREAKPOINT"};const n=t.condition();return t.isLogpoint()?{type:"LOGPOINT",hoverText:n}:{type:"CONDITIONAL_BREAKPOINT",hoverText:n}}#h(e){const t=this.#t.get(e);return i(t),t}async#f(){const e=m.Context.Context.instance().flavor(a.DebuggerModel.DebuggerPausedDetails);return e&&e.callFrames.length?await r.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().rawLocationToUILocation(e.callFrames[0].location()):null}#g(){const e=this.#e.allBreakpointLocations().filter((e=>e.uiLocation.uiSourceCode.project().type()!==l.Workspace.projectTypes.Debugger));e.sort(((e,t)=>e.uiLocation.compareTo(t.uiLocation)));const t=[];let n=null,o=null;for(const i of e)(i.breakpoint!==n||o&&i.uiLocation.compareTo(o))&&(t.push(i),n=i.breakpoint,o=i.uiLocation);return t}#m(e){const t=new o.MapUtilities.Multimap;for(const n of e){const e=n.uiLocation;t.set(e.id(),n)}const n=[];for(const e of t.keysArray()){const o=Array.from(t.get(e));o.length&&n.push(o)}return n}#b(e){const t=new o.MapUtilities.Multimap;for(const n of e){const e=n.uiLocation;t.set(e.lineId(),e.id())}return t}#x(e){const t=e.some((e=>e.breakpoint.enabled())),n=e.some((e=>!e.breakpoint.enabled()));let o;return o=t?n?"INDETERMINATE":"ENABLED":"DISABLED",o}#k(e){const t=new Map;return Promise.all(e.map((async([{uiLocation:{uiSourceCode:e}}])=>{const n=await e.requestContent({cachedWasmOnly:!0});if("wasmDisassemblyInfo"in n&&n.wasmDisassemblyInfo)return n.wasmDisassemblyInfo;const o=n.content||"";if(t.has(o))return t.get(o);const i=new c.Text.Text(o);return t.set(o,i),i})))}}class F extends u.LegacyWrapper.WrappableComponent{#y;static instance({forceNew:e}={forceNew:!1}){return R&&!e||(R=u.LegacyWrapper.legacyWrapper(m.Widget.Widget,new F)),R.getComponent()}constructor(){super(),this.#y=U.instance(),this.#y.update()}static litTagName=b.literal`devtools-breakpoint-view`;#w=this.attachShadow({mode:"open"});#S=!1;#E=!1;#C=!1;#I=!0;#T=[];#B=new Map;set data(e){this.#S=e.pauseOnUncaughtExceptions,this.#E=e.pauseOnCaughtExceptions,this.#C=e.independentPauseToggles,this.#I=e.breakpointsActive,this.#T=e.groups;const t=[];for(const n of e.groups)t.push({name:n.name,url:n.url});this.#B=$(t),this.render()}connectedCallback(){this.#w.adoptedStyleSheets=[h.checkboxStyles,x]}async render(){await D.write("BreakpointsView render",(()=>{const e=async e=>{const t=e.currentTarget;await this.#L(t),e.consume()},t=(this.#C||this.#S)&&this.#E,n=!this.#C&&!this.#S,o=b.html` <div class="pause-on-uncaught-exceptions" tabindex="0" @click="${e}" @keydown="${this.#$}" data-first-pause> <label class="checkbox-label"> <input type="checkbox" tabindex="-1" ?checked="${this.#S}" @change="${this.#O.bind(this)}"> <span>${N(A.pauseOnUncaughtExceptions)}</span> </label> </div> <div class="pause-on-caught-exceptions" tabindex="-1" @click="${e}" @keydown="${this.#$}" data-last-pause> <label class="checkbox-label"> <input data-pause-on-caught-checkbox type="checkbox" tabindex="-1" ?checked="${t}" ?disabled="${n}" @change="${this.#A.bind(this)}"> <span>${N(A.pauseOnCaughtExceptions)}</span> </label> </div> <div role="tree"> ${b.Directives.repeat(this.#T,(e=>e.url),((e,t)=>b.html`${this.#M(e,t)}`))} </div>`;b.render(o,this.#w,{host:this})})),await D.write("make pause-on-exceptions focusable",(()=>{if(null===this.#w.querySelector('[tabindex="0"]')){this.#w.querySelector("[data-first-pause]")?.setAttribute("tabindex","0")}}))}async#$(e){if(e.target&&e.target instanceof HTMLElement){if("Home"===e.key||"End"===e.key)return e.consume(!0),this.#N(e.key);if(o.KeyboardUtilities.keyIsArrowKey(e.key))return e.consume(!0),this.#D(e.key,e.target);if(o.KeyboardUtilities.isEnterOrSpaceKey(e)){const t=e.currentTarget;await this.#L(t);const n=t.getElementsByTagName("input");1===n.length&&(n[0].checked=!n[0].checked),e.consume()}}}async#L(e){e&&D.write("focus on selected element",(()=>{this.#w.querySelector('[tabindex="0"]')?.setAttribute("tabindex","-1"),e.setAttribute("tabindex","0"),e.focus()}))}async#D(e,t){const n=await T(t,e,((e,t)=>t?D.write("expand",(()=>{e.setAttribute("open","")})):D.write("expand",(()=>{e.removeAttribute("open")}))));return this.#L(n)}async#N(e){if("Home"===e){const e=this.#w.querySelector("[data-first-pause]");return this.#L(e)}if("End"===e){const e=this.#T.length;if(0===e){const e=this.#w.querySelector("[data-last-pause]");return this.#L(e)}const t=e-1;if(this.#T[t].expanded){const e=this.#w.querySelector("[data-last-group] > [data-last-breakpoint]");return this.#L(e)}const n=this.#w.querySelector("[data-last-group] > summary");return this.#L(n)}}#R(e){const n="LOGPOINT"===e.type?N(A.editLogpoint):N(A.editCondition);return b.html` <button data-edit-breakpoint @click="${n=>{t.userMetrics.breakpointEditDialogRevealedFrom(1),this.#y.breakpointEdited(e,!0),n.consume()}}" title="${n}"> <${p.Icon.Icon.litTagName} .data="${{iconName:"edit",width:"16px",height:"16px",color:"var(--icon-default)"}}"> </${p.Icon.Icon.litTagName}> </button> `}#H(e,n,o){return b.html` <button data-remove-breakpoint @click="${n=>{t.userMetrics.actionTaken(o),this.#y.breakpointsRemoved(e),n.consume()}}" title="${n}" aria-label="${n}"> <${p.Icon.Icon.litTagName} .data="${{iconName:"cross",width:"20px",height:"20px",color:"var(--icon-default)"}}" }> </${p.Icon.Icon.litTagName}> </button> `}#U(e,n){const{breakpointItems:o}=n,i=new m.ContextMenu.ContextMenu(e);i.defaultSection().appendItem(N(A.removeAllBreakpointsInFile),(()=>{t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointsInFileRemovedFromContextMenu),this.#y.breakpointsRemoved(o)}));const a=this.#T.filter((e=>e!==n));i.defaultSection().appendItem(N(A.removeOtherBreakpoints),(()=>{const e=a.map((({breakpointItems:e})=>e)).flat();this.#y.breakpointsRemoved(e)}),0===a.length),i.defaultSection().appendItem(N(A.removeAllBreakpoints),(()=>{const e=this.#T.map((({breakpointItems:e})=>e)).flat();this.#y.breakpointsRemoved(e)}));const r=o.filter((e=>"ENABLED"!==e.status));i.debugSection().appendItem(N(A.enableAllBreakpointsInFile),(()=>{t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointsInFileEnabledDisabledFromContextMenu);for(const e of r)this.#y.breakpointStateChanged(e,!0)}),0===r.length);const s=o.filter((e=>"DISABLED"!==e.status));i.debugSection().appendItem(N(A.disableAllBreakpointsInFile),(()=>{t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointsInFileEnabledDisabledFromContextMenu);for(const e of s)this.#y.breakpointStateChanged(e,!1)}),0===s.length),i.show()}#M(e,n){const o={active:this.#I};return b.html` <details class="${b.Directives.classMap(o)}" ?data-first-group="${0===n}" ?data-last-group="${n===this.#T.length-1}" role="group" aria-label="${e.name}" aria-description="${e.url}" ?open="${b.Directives.live(e.expanded)}" @toggle="${t=>{const n=t.target;e.expanded=n.open,this.#y.expandedStateChanged(e.url,e.expanded)}}"> <summary @contextmenu="${t=>{this.#U(t,e),t.consume()}}" tabindex="-1" @keydown="${this.#$}" @click="${async e=>{const n=e.currentTarget;await this.#L(n),t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointGroupExpandedStateChanged),e.consume()}}"> <span class="group-header" aria-hidden="true"><span class="group-icon-or-disable">${this.#F()}${this.#P(e)}</span><span class="group-header-title" title="${e.url}">${e.name}<span class="group-header-differentiator">${this.#B.get(e.url)}</span></span></span> <span class="group-hover-actions"> ${this.#H(e.breakpointItems,N(A.removeAllBreakpointsInFile),t.UserMetrics.Action.BreakpointsInFileRemovedFromRemoveButton)} </span> </summary> ${b.Directives.repeat(e.breakpointItems,(e=>e.id),((t,o)=>this.#j(t,e.editable,n,o)))} </details> `}#P(e){const n=e.breakpointItems.some((e=>"ENABLED"===e.status));return b.html` <input class="group-checkbox" type="checkbox" aria-label="" .checked="${n}" @change="${n=>{t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointsInFileCheckboxToggled);const o=n.target,i=o.checked?"ENABLED":"DISABLED";e.breakpointItems.filter((e=>e.status!==i)).forEach((e=>{this.#y.breakpointStateChanged(e,o.checked)})),n.consume()}}" tabindex="-1"> `}#F(){return b.html` <${p.Icon.Icon.litTagName} class="file-icon" .data="${{iconName:"file-script",color:"var(--icon-file-script)",width:"18px",height:"18px"}}"></${p.Icon.Icon.litTagName}> `}#W(e,n,o){const i=new m.ContextMenu.ContextMenu(e),a="LOGPOINT"===n.type?N(A.editLogpoint):N(A.editCondition);i.revealSection().appendItem(a,(()=>{t.userMetrics.breakpointEditDialogRevealedFrom(0),this.#y.breakpointEdited(n,!1)}),!o),i.defaultSection().appendItem(N(A.removeBreakpoint),(()=>{t.userMetrics.actionTaken(t.UserMetrics.Action.BreakpointRemovedFromContextMenu),this.#y.breakpointsRemoved([n])}));const r=this.#T.map((({breakpointItems:e})=>e)).flat().filter((e=>e!==n));i.defaultSection().appendItem(N(A.removeOtherBreakpoints),(()=>{this.#y.breakpointsRemoved(r)}),0===r.length),i.defaultSection().appendItem(N(A.removeAllBreakpoints),(()=>{const e=this.#T.map((({breakpointItems:e})=>e)).flat();this.#y.breakpointsRemoved(e)})),i.editSection().appendItem(N(A.revealLocation),(()=>{this.#y.jumpToSource(n)})),i.show()}#j(e,n,i,a){const r={"breakpoint-item":!0,hit:e.isHit,"conditional-breakpoint":"CONDITIONAL_BREAKPOINT"===e.type,logpoint:"LOGPOINT"===e.type},s=this.#_(e),c=o.StringUtilities.trimEndWithMaxLength(e.codeSnippet,200),l=this.#G(e.type,e.hoverText),d=this.#T[i].breakpointItems;return b.html` <div class="${b.Directives.classMap(r)}" ?data-first-breakpoint="${0===a}" ?data-last-breakpoint="${a===d.length-1}" aria-label="${s}" role="treeitem" tabindex="-1" @contextmenu="${t=>{this.#W(t,e,n),t.consume()}}" @click="${async e=>{const t=e.currentTarget;await this.#L(t),e.consume()}}" @keydown="${this.#$}"> <label class="checkbox-label"> <span class="type-indicator"></span> <input type="checkbox" aria-label="${e.location}" ?indeterminate="${"INDETERMINATE"===e.status}" .checked="${"ENABLED"===e.status}" @change="${t=>this.#V(t,e)}" tabindex="-1"> </label> <span class="code-snippet" @click="${t=>{this.#y.jumpToSource(e),t.consume()}}" title="${l}">${c}</span> <span class="breakpoint-item-location-or-actions"> ${n?this.#R(e):b.nothing} ${this.#H([e],N(A.removeBreakpoint),t.UserMetrics.Action.BreakpointRemovedFromRemoveButton)} <span class="location">${e.location}</span> </span> </div> `}#G(e,t){switch(e){case"REGULAR_BREAKPOINT":return;case"CONDITIONAL_BREAKPOINT":return i(t),N(A.conditionCode,{PH1:t});case"LOGPOINT":return i(t),N(A.logpointCode,{PH1:t})}}#_(e){let t;switch(e.status){case"ENABLED":t=N(A.checked);break;case"DISABLED":t=N(A.unchecked);break;case"INDETERMINATE":t=N(A.indeterminate)}return e.isHit?N(A.breakpointHit,{PH1:t}):t}#V(e,t){const n=e.target;this.#y.breakpointStateChanged(t,n.checked)}#A(e){const{checked:t}=e.target;this.#y.setPauseOnCaughtExceptions(t)}#O(e){const{checked:t}=e.target;if(!this.#C){const e=this.#w.querySelector("[data-pause-on-caught-checkbox]");i(e),!t&&e.checked&&e.click(),D.write("update pause-on-uncaught-exception",(()=>{e.disabled=!t}))}this.#y.setPauseOnUncaughtExceptions(t)}}d.CustomElements.defineComponent("devtools-breakpoint-view",F);var P=Object.freeze({__proto__:null,BreakpointsSidebarController:U,BreakpointsView:F});const j=new CSSStyleSheet;j.replaceSync(":host{flex-grow:1;padding:6px}.row{display:flex;flex-direction:row;color:var(--color-syntax-1);font-family:var(--monospace-font-family);font-size:var(--monospace-font-size);align-items:center;line-height:24px}.row devtools-button{line-height:1;margin-left:0.1em}.row devtools-button:nth-of-type(1){margin-left:0.8em}.padded{margin-left:2em}.separator{margin-right:0.5em;color:var(--color-text-primary)}.editable{cursor:text;color:var(--color-text-primary);overflow-wrap:break-word;min-height:18px;line-height:18px;min-width:0.5em;background:transparent;border:none;outline:none;display:inline-block}.editable.red{color:var(--color-syntax-1)}.editable:hover,\n.editable:focus{box-shadow:0 0 0 1px var(--color-details-hairline);border-radius:2px}.row .inline-button{opacity:0%;visibility:hidden;transition:opacity 200ms}.row:focus-within .inline-button,\n.row:hover .inline-button{opacity:100%;visibility:visible}.center-wrapper{height:100%;display:flex;justify-content:center;align-items:center}.centered{margin:1em;max-width:300px;text-align:center}.error-header{font-weight:bold;margin-bottom:1em}.error-body{line-height:1.5em;color:var(--color-text-secondary)}.add-block{margin-top:3px}.header-name,\n.header-value{min-width:min-content}.link{color:var(--color-link);text-decoration:underline;cursor:pointer;outline-offset:2px;padding:0}.learn-more-row{line-height:24px}\n/*# sourceURL=HeadersView.css */\n");const W={addHeader:"Add a header",removeHeader:"Remove this header",removeBlock:"Remove this '`ApplyTo`'-section",errorWhenParsing:"Error when parsing ''{PH1}''.",parsingErrorExplainer:"This is most likely due to a syntax error in ''{PH1}''. Try opening this file in an external editor to fix the error or delete the file and re-create the override.",addOverrideRule:"Add override rule",learnMore:"Learn more"},_=n.i18n.registerUIStrings("panels/sources/components/HeadersView.ts",W),G=n.i18n.getLocalizedString.bind(void 0,_),V=new URL("../../../Images/plus.svg",import.meta.url).toString(),q=new URL("../../../Images/bin.svg",import.meta.url).toString();class z extends m.View.SimpleView{#q=new K;#z;constructor(e){super(n.i18n.lockedString("HeadersView")),this.#z=e,this.#z.addEventListener(l.UISourceCode.Events.WorkingCopyChanged,this.#K,this),this.#z.addEventListener(l.UISourceCode.Events.WorkingCopyCommitted,this.#J,this),this.element.appendChild(this.#q),this.#Q()}async#Q(){const e=await this.#z.requestContent();this.#X(e.content||"")}#X(e){let t=!1,n=[];e=e||"[]";try{if(n=JSON.parse(e),!n.every(k.NetworkPersistenceManager.isHeaderOverride))throw"Type mismatch after parsing"}catch(e){console.error("Failed to parse",this.#z.url(),"for locally overriding headers."),t=!0}this.#q.data={headerOverrides:n,uiSourceCode:this.#z,parsingError:t}}#K(){this.#X(this.#z.workingCopy())}#J(){this.#X(this.#z.workingCopy())}getComponent(){return this.#q}dispose(){this.#z.removeEventListener(l.UISourceCode.Events.WorkingCopyChanged,this.#K,this),this.#z.removeEventListener(l.UISourceCode.Events.WorkingCopyCommitted,this.#J,this)}}class K extends HTMLElement{static litTagName=b.literal`devtools-sources-headers-view`;#w=this.attachShadow({mode:"open"});#Y=this.#Z.bind(this);#ee=[];#z=null;#te=!1;#ne=null;#oe="";constructor(){super(),this.#w.addEventListener("focusin",this.#ie.bind(this)),this.#w.addEventListener("focusout",this.#ae.bind(this)),this.#w.addEventListener("click",this.#re.bind(this)),this.#w.addEventListener("input",this.#se.bind(this)),this.#w.addEventListener("keydown",this.#ce.bind(this)),this.#w.addEventListener("paste",this.#le.bind(this)),this.addEventListener("contextmenu",this.#de.bind(this))}connectedCallback(){this.#w.adoptedStyleSheets=[j]}set data(e){this.#ee=e.headerOverrides,this.#z=e.uiSourceCode,this.#te=e.parsingError,d.ScheduledRender.scheduleRender(this,this.#Y)}#ce(e){const t=e.target;if(!t.matches(".editable"))return;const n=e;!t.matches(".header-name")||""!==t.innerText||"Enter"!==n.key&&"Tab"!==n.key?"Enter"===n.key?(e.preventDefault(),t.blur(),this.#pe(t)):"Escape"===n.key&&(e.consume(),t.innerText=this.#oe,t.blur(),this.#he(t)):(e.preventDefault(),t.blur())}#pe(e){const t=Array.from(this.#w.querySelectorAll(".editable")),n=t.indexOf(e);-1!==n&&n+1<t.length&&t[n+1].focus()}#ue(e){const t=window.getSelection(),n=document.createRange();n.selectNodeContents(e),t?.removeAllRanges(),t?.addRange(n)}#ie(e){const t=e.target;t.matches(".editable")&&(this.#ue(t),this.#oe=t.innerText)}#ae(e){const t=e.target;if(""===t.innerText){const e=t.closest(".row"),n=Number(e.dataset.blockIndex),o=Number(e.dataset.headerIndex);t.matches(".apply-to")?(t.innerText="*",this.#ee[n].applyTo="*",this.#ge()):t.matches(".header-name")&&this.#me(n,o)}window.getSelection()?.removeAllRanges(),this.#z?.commitWorkingCopy()}#de(e){if(!this.#z)return;const t=new m.ContextMenu.ContextMenu(e);t.appendApplicableItems(this.#z),t.show()}#be(e){const t=new Set(e.map((e=>e.name)));let n=1;for(;t.has("header-name-"+n);)n++;return"header-name-"+n}#re(e){const t=e.target,n=t.closest(".row"),o=Number(n?.dataset.blockIndex||0),i=Number(n?.dataset.headerIndex||0);t.matches(".add-header")?(this.#ee[o].headers.splice(i+1,0,{name:this.#be(this.#ee[o].headers),value:"header value"}),this.#ne={blockIndex:o,headerIndex:i+1},this.#ge()):t.matches(".remove-header")?this.#me(o,i):t.matches(".add-block")?(this.#ee.push({applyTo:"*",headers:[{name:"header-name-1",value:"header value"}]}),this.#ne={blockIndex:this.#ee.length-1},this.#ge()):t.matches(".remove-block")&&(this.#ee.splice(o,1),this.#ge())}#me(e,t){this.#ee[e].headers.splice(t,1),0===this.#ee[e].headers.length&&this.#ee[e].headers.push({name:this.#be(this.#ee[e].headers),value:"header value"}),this.#ge()}#se(e){this.#he(e.target)}#he(e){const t=e.closest(".row"),n=Number(t.dataset.blockIndex),o=Number(t.dataset.headerIndex);e.matches(".header-name")&&(this.#ee[n].headers[o].name=e.innerText,this.#ge()),e.matches(".header-value")&&(this.#ee[n].headers[o].value=e.innerText,this.#ge()),e.matches(".apply-to")&&(this.#ee[n].applyTo=e.innerText,this.#ge())}#ge(){this.#z?.setWorkingCopy(JSON.stringify(this.#ee,null,2)),t.userMetrics.actionTaken(t.UserMetrics.Action.HeaderOverrideHeadersFileEdited)}#le(e){const t=e;if(e.preventDefault(),t.clipboardData){const n=t.clipboardData.getData("text/plain"),o=this.#w.getSelection()?.getRangeAt(0);if(!o)return;o.deleteContents();const i=document.createTextNode(n);o.insertNode(i),o.selectNodeContents(i),o.collapse(!1);const a=window.getSelection();a?.removeAllRanges(),a?.addRange(o),this.#he(e.target)}}#Z(){if(!d.ScheduledRender.isScheduledRender(this))throw new Error("HeadersView render was not scheduled");if(this.#te){const e=this.#z?.name()||".headers";b.render(b.html` <div class="center-wrapper"> <div class="centered"> <div class="error-header">${G(W.errorWhenParsing,{PH1:e})}</div> <div class="error-body">${G(W.parsingErrorExplainer,{PH1:e})}</div> </div> </div> `,this.#w,{host:this})}else if(b.render(b.html` ${this.#ee.map(((e,t)=>b.html` ${this.#ke(e.applyTo,t)} ${e.headers.map(((e,n)=>b.html` ${this.#fe(e,t,n)} `))} `))} <${f.Button.Button.litTagName} .variant="${"secondary"}" class="add-block"> ${G(W.addOverrideRule)} </${f.Button.Button.litTagName}> <div class="learn-more-row"> <x-link href="https://goo.gle/devtools-override" class="link">${G(W.learnMore)}</x-link> </div> `,this.#w,{host:this}),this.#ne){let e=null;e=this.#ne.headerIndex?this.#w.querySelector(`[data-block-index="${this.#ne.blockIndex}"][data-header-index="${this.#ne.headerIndex}"] .header-name`):this.#w.querySelector(`[data-block-index="${this.#ne.blockIndex}"] .apply-to`),e&&e.focus(),this.#ne=null}}#ke(e,t){return b.html` <div class="row" data-block-index="${t}"> <div>${n.i18n.lockedString("Apply to")}</div> <div class="separator">:</div> ${this.#xe(e,"apply-to")} <${f.Button.Button.litTagName} title="${G(W.removeBlock)}" .size="${"SMALL"}" .iconUrl="${q}" .iconWidth="${"14px"}" .iconHeight="${"14px"}" .variant="${"round"}" class="remove-block inline-button"></${f.Button.Button.litTagName}> </div> `}#fe(e,t,n){return b.html` <div class="row padded" data-block-index="${t}" data-header-index="${n}"> ${this.#xe(e.name,"header-name red")} <div class="separator">:</div> ${this.#xe(e.value,"header-value")} <${f.Button.Button.litTagName} title="${G(W.addHeader)}" .size="${"SMALL"}" .iconUrl="${V}" .iconWidth="${"20px"}" .iconHeight="${"20px"}" .variant="${"round"}" class="add-header inline-button"></${f.Button.Button.litTagName}> <${f.Button.Button.litTagName} title="${G(W.removeHeader)}" .size="${"SMALL"}" .iconUrl="${q}" .iconWidth="${"14px"}" .iconHeight="${"14px"}" .variant="${"round"}" class="remove-header inline-button"></${f.Button.Button.litTagName}> </div> `}#xe(e,t){return b.html`<span contenteditable="true" class="editable ${t}" tabindex="0" .innerText="${b.Directives.live(e)}"></span>`}}d.CustomElements.defineComponent("devtools-sources-headers-view",K);var J=Object.freeze({__proto__:null,HeadersView:z,HeadersViewComponent:K});export{P as BreakpointsView,O as BreakpointsViewUtils,J as HeadersView};
